/*
 * Copyright 2024 LinQingYing. and contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of this source code is governed by the Apache License 2.0,
 * which allows users to freely use, modify, and distribute the code,
 * provided they adhere to the terms of the license.
 *
 * The software is provided "as-is", and the authors are not responsible for
 * any damages or issues arising from its use.
 *
 */

package com.linqingying.cangjie.resolve.constants.evaluate

import com.linqingying.cangjie.parsing.Float16
import java.math.BigInteger

fun evalBinaryOp(name: String, leftType: CompileTimeType, left: Any, rightType: CompileTimeType, right: Any): Any? {
    when (leftType) {
        CompileTimeType.Bool -> when (rightType) {
            CompileTimeType.Bool -> when (name) {
                "*operator_and" -> return (left as Boolean).and(right as Boolean)
                "*operator_compare_gt" -> return (left as Boolean).compareTo(right as Boolean)
                "*operator_compare_lt" -> return (right as Boolean).compareTo(left as Boolean)


                "*operator_or" -> return (left as Boolean).or(right as Boolean)
                "*operator_xor" -> return (left as Boolean).xor(right as Boolean)
            }

            CompileTimeType.Any -> when (name) {
                "**operator_not_equals" -> return (left as Boolean) == right
                "*operator_equals" -> return (left as Boolean) == right
            }

            else -> {}
        }
//
//        BYTE -> when (rightType) {
//            BYTE -> when (name) {
//                "compareTo" -> return (left as Byte).compareTo(right as Byte)
//                "div" -> return (left as Byte).div(right as Byte)
//                "minus" -> return (left as Byte).minus(right as Byte)
//                "plus" -> return (left as Byte).plus(right as Byte)
//                "rem" -> return (left as Byte).rem(right as Byte)
//                "times" -> return (left as Byte).times(right as Byte)
//                "mod" -> return (left as Byte).mod(right as Byte)
//                "floorDiv" -> return (left as Byte).floorDiv(right as Byte)
//            }
//
//            DOUBLE -> when (name) {
//                "compareTo" -> return (left as Byte).compareTo(right as Double)
//                "div" -> return (left as Byte).div(right as Double)
//                "minus" -> return (left as Byte).minus(right as Double)
//                "plus" -> return (left as Byte).plus(right as Double)
//                "rem" -> return (left as Byte).rem(right as Double)
//                "times" -> return (left as Byte).times(right as Double)
//            }
//
//            FLOAT -> when (name) {
//                "compareTo" -> return (left as Byte).compareTo(right as Float)
//                "div" -> return (left as Byte).div(right as Float)
//                "minus" -> return (left as Byte).minus(right as Float)
//                "plus" -> return (left as Byte).plus(right as Float)
//                "rem" -> return (left as Byte).rem(right as Float)
//                "times" -> return (left as Byte).times(right as Float)
//            }
//
//            INT -> when (name) {
//                "compareTo" -> return (left as Byte).compareTo(right as Int)
//                "div" -> return (left as Byte).div(right as Int)
//                "minus" -> return (left as Byte).minus(right as Int)
//                "plus" -> return (left as Byte).plus(right as Int)
//                "rem" -> return (left as Byte).rem(right as Int)
//                "times" -> return (left as Byte).times(right as Int)
//                "mod" -> return (left as Byte).mod(right as Int)
//                "floorDiv" -> return (left as Byte).floorDiv(right as Int)
//            }
//
//            LONG -> when (name) {
//                "compareTo" -> return (left as Byte).compareTo(right as Long)
//                "div" -> return (left as Byte).div(right as Long)
//                "minus" -> return (left as Byte).minus(right as Long)
//                "plus" -> return (left as Byte).plus(right as Long)
//                "rem" -> return (left as Byte).rem(right as Long)
//                "times" -> return (left as Byte).times(right as Long)
//                "mod" -> return (left as Byte).mod(right as Long)
//                "floorDiv" -> return (left as Byte).floorDiv(right as Long)
//            }
//
//            SHORT -> when (name) {
//                "compareTo" -> return (left as Byte).compareTo(right as Short)
//                "div" -> return (left as Byte).div(right as Short)
//                "minus" -> return (left as Byte).minus(right as Short)
//                "plus" -> return (left as Byte).plus(right as Short)
//                "rem" -> return (left as Byte).rem(right as Short)
//                "times" -> return (left as Byte).times(right as Short)
//                "mod" -> return (left as Byte).mod(right as Short)
//                "floorDiv" -> return (left as Byte).floorDiv(right as Short)
//            }
//
//            ANY -> when (name) {
//                "equals" -> return (left as Byte).equals(right)
//            }
//
//            else -> {}
//        }
//
//        CHAR -> when (rightType) {
//            CHAR -> when (name) {
//                "compareTo" -> return (left as Char).compareTo(right as Char)
//                "minus" -> return (left as Char).minus(right as Char)
//            }
//
//            ANY -> when (name) {
//                "equals" -> return (left as Char).equals(right)
//            }
//
//            INT -> when (name) {
//                "minus" -> return (left as Char).minus(right as Int)
//                "plus" -> return (left as Char).plus(right as Int)
//            }
//
//            else -> {}
//        }
//
//        DOUBLE -> when (rightType) {
//            BYTE -> when (name) {
//                "compareTo" -> return (left as Double).compareTo(right as Byte)
//                "div" -> return (left as Double).div(right as Byte)
//                "minus" -> return (left as Double).minus(right as Byte)
//                "plus" -> return (left as Double).plus(right as Byte)
//                "rem" -> return (left as Double).rem(right as Byte)
//                "times" -> return (left as Double).times(right as Byte)
//            }
//
//            DOUBLE -> when (name) {
//                "compareTo" -> return (left as Double).compareTo(right as Double)
//                "div" -> return (left as Double).div(right as Double)
//                "minus" -> return (left as Double).minus(right as Double)
//                "plus" -> return (left as Double).plus(right as Double)
//                "rem" -> return (left as Double).rem(right as Double)
//                "times" -> return (left as Double).times(right as Double)
//                "mod" -> return (left as Double).mod(right as Double)
//            }
//
//            FLOAT -> when (name) {
//                "compareTo" -> return (left as Double).compareTo(right as Float)
//                "div" -> return (left as Double).div(right as Float)
//                "minus" -> return (left as Double).minus(right as Float)
//                "plus" -> return (left as Double).plus(right as Float)
//                "rem" -> return (left as Double).rem(right as Float)
//                "times" -> return (left as Double).times(right as Float)
//                "mod" -> return (left as Double).mod(right as Float)
//            }
//
//            INT -> when (name) {
//                "compareTo" -> return (left as Double).compareTo(right as Int)
//                "div" -> return (left as Double).div(right as Int)
//                "minus" -> return (left as Double).minus(right as Int)
//                "plus" -> return (left as Double).plus(right as Int)
//                "rem" -> return (left as Double).rem(right as Int)
//                "times" -> return (left as Double).times(right as Int)
//            }
//
//            LONG -> when (name) {
//                "compareTo" -> return (left as Double).compareTo(right as Long)
//                "div" -> return (left as Double).div(right as Long)
//                "minus" -> return (left as Double).minus(right as Long)
//                "plus" -> return (left as Double).plus(right as Long)
//                "rem" -> return (left as Double).rem(right as Long)
//                "times" -> return (left as Double).times(right as Long)
//            }
//
//            SHORT -> when (name) {
//                "compareTo" -> return (left as Double).compareTo(right as Short)
//                "div" -> return (left as Double).div(right as Short)
//                "minus" -> return (left as Double).minus(right as Short)
//                "plus" -> return (left as Double).plus(right as Short)
//                "rem" -> return (left as Double).rem(right as Short)
//                "times" -> return (left as Double).times(right as Short)
//            }
//
//            ANY -> when (name) {
//                "equals" -> return (left as Double).equals(right)
//            }
//
//            else -> {}
//        }
//
//        FLOAT -> when (rightType) {
//            BYTE -> when (name) {
//                "compareTo" -> return (left as Float).compareTo(right as Byte)
//                "div" -> return (left as Float).div(right as Byte)
//                "minus" -> return (left as Float).minus(right as Byte)
//                "plus" -> return (left as Float).plus(right as Byte)
//                "rem" -> return (left as Float).rem(right as Byte)
//                "times" -> return (left as Float).times(right as Byte)
//            }
//
//            DOUBLE -> when (name) {
//                "compareTo" -> return (left as Float).compareTo(right as Double)
//                "div" -> return (left as Float).div(right as Double)
//                "minus" -> return (left as Float).minus(right as Double)
//                "plus" -> return (left as Float).plus(right as Double)
//                "rem" -> return (left as Float).rem(right as Double)
//                "times" -> return (left as Float).times(right as Double)
//                "mod" -> return (left as Float).mod(right as Double)
//            }
//
//            FLOAT -> when (name) {
//                "compareTo" -> return (left as Float).compareTo(right as Float)
//                "div" -> return (left as Float).div(right as Float)
//                "minus" -> return (left as Float).minus(right as Float)
//                "plus" -> return (left as Float).plus(right as Float)
//                "rem" -> return (left as Float).rem(right as Float)
//                "times" -> return (left as Float).times(right as Float)
//                "mod" -> return (left as Float).mod(right as Float)
//            }
//
//            INT -> when (name) {
//                "compareTo" -> return (left as Float).compareTo(right as Int)
//                "div" -> return (left as Float).div(right as Int)
//                "minus" -> return (left as Float).minus(right as Int)
//                "plus" -> return (left as Float).plus(right as Int)
//                "rem" -> return (left as Float).rem(right as Int)
//                "times" -> return (left as Float).times(right as Int)
//            }
//
//            LONG -> when (name) {
//                "compareTo" -> return (left as Float).compareTo(right as Long)
//                "div" -> return (left as Float).div(right as Long)
//                "minus" -> return (left as Float).minus(right as Long)
//                "plus" -> return (left as Float).plus(right as Long)
//                "rem" -> return (left as Float).rem(right as Long)
//                "times" -> return (left as Float).times(right as Long)
//            }
//
//            SHORT -> when (name) {
//                "compareTo" -> return (left as Float).compareTo(right as Short)
//                "div" -> return (left as Float).div(right as Short)
//                "minus" -> return (left as Float).minus(right as Short)
//                "plus" -> return (left as Float).plus(right as Short)
//                "rem" -> return (left as Float).rem(right as Short)
//                "times" -> return (left as Float).times(right as Short)
//            }
//
//            ANY -> when (name) {
//                "equals" -> return (left as Float).equals(right)
//            }
//
//            else -> {}
//        }
//
//        INT -> when (rightType) {
//            INT -> when (name) {
//                "and" -> return (left as Int).and(right as Int)
//                "compareTo" -> return (left as Int).compareTo(right as Int)
//                "div" -> return (left as Int).div(right as Int)
//                "minus" -> return (left as Int).minus(right as Int)
//                "or" -> return (left as Int).or(right as Int)
//                "plus" -> return (left as Int).plus(right as Int)
//                "rem" -> return (left as Int).rem(right as Int)
//                "shl" -> return (left as Int).shl(right as Int)
//                "shr" -> return (left as Int).shr(right as Int)
//                "times" -> return (left as Int).times(right as Int)
//                "ushr" -> return (left as Int).ushr(right as Int)
//                "xor" -> return (left as Int).xor(right as Int)
//                "mod" -> return (left as Int).mod(right as Int)
//                "floorDiv" -> return (left as Int).floorDiv(right as Int)
//            }
//
//            BYTE -> when (name) {
//                "compareTo" -> return (left as Int).compareTo(right as Byte)
//                "div" -> return (left as Int).div(right as Byte)
//                "minus" -> return (left as Int).minus(right as Byte)
//                "plus" -> return (left as Int).plus(right as Byte)
//                "rem" -> return (left as Int).rem(right as Byte)
//                "times" -> return (left as Int).times(right as Byte)
//                "mod" -> return (left as Int).mod(right as Byte)
//                "floorDiv" -> return (left as Int).floorDiv(right as Byte)
//            }
//
//            DOUBLE -> when (name) {
//                "compareTo" -> return (left as Int).compareTo(right as Double)
//                "div" -> return (left as Int).div(right as Double)
//                "minus" -> return (left as Int).minus(right as Double)
//                "plus" -> return (left as Int).plus(right as Double)
//                "rem" -> return (left as Int).rem(right as Double)
//                "times" -> return (left as Int).times(right as Double)
//            }
//
//            FLOAT -> when (name) {
//                "compareTo" -> return (left as Int).compareTo(right as Float)
//                "div" -> return (left as Int).div(right as Float)
//                "minus" -> return (left as Int).minus(right as Float)
//                "plus" -> return (left as Int).plus(right as Float)
//                "rem" -> return (left as Int).rem(right as Float)
//                "times" -> return (left as Int).times(right as Float)
//            }
//
//            LONG -> when (name) {
//                "compareTo" -> return (left as Int).compareTo(right as Long)
//                "div" -> return (left as Int).div(right as Long)
//                "minus" -> return (left as Int).minus(right as Long)
//                "plus" -> return (left as Int).plus(right as Long)
//                "rem" -> return (left as Int).rem(right as Long)
//                "times" -> return (left as Int).times(right as Long)
//                "mod" -> return (left as Int).mod(right as Long)
//                "floorDiv" -> return (left as Int).floorDiv(right as Long)
//            }
//
//            SHORT -> when (name) {
//                "compareTo" -> return (left as Int).compareTo(right as Short)
//                "div" -> return (left as Int).div(right as Short)
//                "minus" -> return (left as Int).minus(right as Short)
//                "plus" -> return (left as Int).plus(right as Short)
//                "rem" -> return (left as Int).rem(right as Short)
//                "times" -> return (left as Int).times(right as Short)
//                "mod" -> return (left as Int).mod(right as Short)
//                "floorDiv" -> return (left as Int).floorDiv(right as Short)
//            }
//
//            ANY -> when (name) {
//                "equals" -> return (left as Int).equals(right)
//            }
//
//            else -> {}
//        }
//
//        LONG -> when (rightType) {
//            LONG -> when (name) {
//                "and" -> return (left as Long).and(right as Long)
//                "compareTo" -> return (left as Long).compareTo(right as Long)
//                "div" -> return (left as Long).div(right as Long)
//                "minus" -> return (left as Long).minus(right as Long)
//                "or" -> return (left as Long).or(right as Long)
//                "plus" -> return (left as Long).plus(right as Long)
//                "rem" -> return (left as Long).rem(right as Long)
//                "times" -> return (left as Long).times(right as Long)
//                "xor" -> return (left as Long).xor(right as Long)
//                "mod" -> return (left as Long).mod(right as Long)
//                "floorDiv" -> return (left as Long).floorDiv(right as Long)
//            }
//
//            BYTE -> when (name) {
//                "compareTo" -> return (left as Long).compareTo(right as Byte)
//                "div" -> return (left as Long).div(right as Byte)
//                "minus" -> return (left as Long).minus(right as Byte)
//                "plus" -> return (left as Long).plus(right as Byte)
//                "rem" -> return (left as Long).rem(right as Byte)
//                "times" -> return (left as Long).times(right as Byte)
//                "mod" -> return (left as Long).mod(right as Byte)
//                "floorDiv" -> return (left as Long).floorDiv(right as Byte)
//            }
//
//            DOUBLE -> when (name) {
//                "compareTo" -> return (left as Long).compareTo(right as Double)
//                "div" -> return (left as Long).div(right as Double)
//                "minus" -> return (left as Long).minus(right as Double)
//                "plus" -> return (left as Long).plus(right as Double)
//                "rem" -> return (left as Long).rem(right as Double)
//                "times" -> return (left as Long).times(right as Double)
//            }
//
//            FLOAT -> when (name) {
//                "compareTo" -> return (left as Long).compareTo(right as Float)
//                "div" -> return (left as Long).div(right as Float)
//                "minus" -> return (left as Long).minus(right as Float)
//                "plus" -> return (left as Long).plus(right as Float)
//                "rem" -> return (left as Long).rem(right as Float)
//                "times" -> return (left as Long).times(right as Float)
//            }
//
//            INT -> when (name) {
//                "compareTo" -> return (left as Long).compareTo(right as Int)
//                "div" -> return (left as Long).div(right as Int)
//                "minus" -> return (left as Long).minus(right as Int)
//                "plus" -> return (left as Long).plus(right as Int)
//                "rem" -> return (left as Long).rem(right as Int)
//                "shl" -> return (left as Long).shl(right as Int)
//                "shr" -> return (left as Long).shr(right as Int)
//                "times" -> return (left as Long).times(right as Int)
//                "ushr" -> return (left as Long).ushr(right as Int)
//                "mod" -> return (left as Long).mod(right as Int)
//                "floorDiv" -> return (left as Long).floorDiv(right as Int)
//            }
//
//            SHORT -> when (name) {
//                "compareTo" -> return (left as Long).compareTo(right as Short)
//                "div" -> return (left as Long).div(right as Short)
//                "minus" -> return (left as Long).minus(right as Short)
//                "plus" -> return (left as Long).plus(right as Short)
//                "rem" -> return (left as Long).rem(right as Short)
//                "times" -> return (left as Long).times(right as Short)
//                "mod" -> return (left as Long).mod(right as Short)
//                "floorDiv" -> return (left as Long).floorDiv(right as Short)
//            }
//
//            ANY -> when (name) {
//                "equals" -> return (left as Long).equals(right)
//            }
//
//            else -> {}
//        }
//
//        SHORT -> when (rightType) {
//            BYTE -> when (name) {
//                "compareTo" -> return (left as Short).compareTo(right as Byte)
//                "div" -> return (left as Short).div(right as Byte)
//                "minus" -> return (left as Short).minus(right as Byte)
//                "plus" -> return (left as Short).plus(right as Byte)
//                "rem" -> return (left as Short).rem(right as Byte)
//                "times" -> return (left as Short).times(right as Byte)
//                "mod" -> return (left as Short).mod(right as Byte)
//                "floorDiv" -> return (left as Short).floorDiv(right as Byte)
//            }
//
//            DOUBLE -> when (name) {
//                "compareTo" -> return (left as Short).compareTo(right as Double)
//                "div" -> return (left as Short).div(right as Double)
//                "minus" -> return (left as Short).minus(right as Double)
//                "plus" -> return (left as Short).plus(right as Double)
//                "rem" -> return (left as Short).rem(right as Double)
//                "times" -> return (left as Short).times(right as Double)
//            }
//
//            FLOAT -> when (name) {
//                "compareTo" -> return (left as Short).compareTo(right as Float)
//                "div" -> return (left as Short).div(right as Float)
//                "minus" -> return (left as Short).minus(right as Float)
//                "plus" -> return (left as Short).plus(right as Float)
//                "rem" -> return (left as Short).rem(right as Float)
//                "times" -> return (left as Short).times(right as Float)
//            }
//
//            INT -> when (name) {
//                "compareTo" -> return (left as Short).compareTo(right as Int)
//                "div" -> return (left as Short).div(right as Int)
//                "minus" -> return (left as Short).minus(right as Int)
//                "plus" -> return (left as Short).plus(right as Int)
//                "rem" -> return (left as Short).rem(right as Int)
//                "times" -> return (left as Short).times(right as Int)
//                "mod" -> return (left as Short).mod(right as Int)
//                "floorDiv" -> return (left as Short).floorDiv(right as Int)
//            }
//
//            LONG -> when (name) {
//                "compareTo" -> return (left as Short).compareTo(right as Long)
//                "div" -> return (left as Short).div(right as Long)
//                "minus" -> return (left as Short).minus(right as Long)
//                "plus" -> return (left as Short).plus(right as Long)
//                "rem" -> return (left as Short).rem(right as Long)
//                "times" -> return (left as Short).times(right as Long)
//                "mod" -> return (left as Short).mod(right as Long)
//                "floorDiv" -> return (left as Short).floorDiv(right as Long)
//            }
//
//            SHORT -> when (name) {
//                "compareTo" -> return (left as Short).compareTo(right as Short)
//                "div" -> return (left as Short).div(right as Short)
//                "minus" -> return (left as Short).minus(right as Short)
//                "plus" -> return (left as Short).plus(right as Short)
//                "rem" -> return (left as Short).rem(right as Short)
//                "times" -> return (left as Short).times(right as Short)
//                "mod" -> return (left as Short).mod(right as Short)
//                "floorDiv" -> return (left as Short).floorDiv(right as Short)
//            }
//
//            ANY -> when (name) {
//                "equals" -> return (left as Short).equals(right)
//            }
//
//            else -> {}
//        }
//
//        STRING -> when (rightType) {
//            STRING -> when (name) {
//                "compareTo" -> return (left as String).compareTo(right as String)
//            }
//
//            ANY -> when (name) {
//                "equals" -> return (left as String).equals(right)
//                "plus" -> return (left as String).plus(right)
//            }
//
//            INT -> when (name) {
//                "get" -> return (left as String).get(right as Int)
//            }
//
//            else -> {}
//        }

        else -> {}
    }
    return null
}

fun checkBinaryOp(
    name: String, leftType: CompileTimeType, left: BigInteger, rightType: CompileTimeType, right: BigInteger
): BigInteger? {
    when (leftType) {
//        BYTE -> when (rightType) {
//            BYTE -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            INT -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            LONG -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            SHORT -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            else -> {}
//        }
//        CompileTimeType.Int32 -> when (rightType) {
//            INT -> when (name) {
//                "and" -> return left.and(right)
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "or" -> return left.or(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//                "xor" -> return left.xor(right)
//            }
//            BYTE -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            LONG -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            SHORT -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            else -> {}
//        }
//        CompileTimeType.Int64 -> when (rightType) {
//            CompileTimeType.Int64  -> when (name) {
//                "and" -> return left.and(right)
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "or" -> return left.or(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//                "xor" -> return left.xor(right)
//            }
//            BYTE -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            INT -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            SHORT -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            else -> {}
//        }
//        SHORT -> when (rightType) {
//            BYTE -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            INT -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            LONG -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            SHORT -> when (name) {
//                "div" -> return left.divide(right)
//                "minus" -> return left.subtract(right)
//                "plus" -> return left.add(right)
//                "rem" -> return left.rem(right)
//                "times" -> return left.multiply(right)
//            }
//            else -> {}
//        }
        else -> {}
    }
    return null
}

fun evalUnaryOp(name: String, type: CompileTimeType, value: Any): Any? {
    when (type) {
        CompileTimeType.Bool -> when (name) {
            "*operator_not" -> return (value as Boolean).not()

        }

        CompileTimeType.Int8 -> when (name) {

            "*operator_unaryMinus" -> return (value as Byte).unaryMinus()
            "*operator_unaryPlus" -> return (value as Byte).unaryPlus()
        }

        CompileTimeType.Flout64 -> when (name) {

            "*operator_unaryMinus" -> return (value as Double).unaryMinus()
            "*operator_unaryPlus" -> return (value as Double).unaryPlus()
        }

        CompileTimeType.Flout32 -> when (name) {

            "*operator_unaryMinus" -> return (value as Float).unaryMinus()
            "*operator_unaryPlus" -> return (value as Float).unaryPlus()
        }

        CompileTimeType.Flout16 -> when (name) {

            "*operator_unaryMinus" -> return (value as Float16).unaryMinus()
            "*operator_unaryPlus" -> return (value as Float16). unaryPlus()
        }

        CompileTimeType.Int32 -> when (name) {

            "*operator_unaryMinus" -> return (value as Int).unaryMinus()
            "*operator_unaryPlus" -> return (value as Int).unaryPlus()
        }

        CompileTimeType.Int64 -> when (name) {

            "*operator_unaryMinus" -> return (value as Long).unaryMinus()
            "*operator_unaryPlus" -> return (value as Long).unaryPlus()
        }

        else -> {}
    }
    return null
}
